1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 21 import com.google.common.annotations.Beta; 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.annotations.GwtIncompatible; 24 import com.google.common.base.Function; 25 import com.google.common.base.Joiner; 26 import com.google.common.base.Optional; 27 import com.google.common.base.Predicate; 28 29 import java.util.Arrays; 30 import java.util.Collection; 31 import java.util.Comparator; 32 import java.util.Iterator; 33 import java.util.List; 34 import java.util.SortedSet; 35 36 import javax.annotation.CheckReturnValue; 37 import javax.annotation.Nullable; 38 39 /** 40 * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a 41 * chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set 42 * of elements. The following types of methods are provided on {@code FluentIterable}: 43 * <ul> 44 * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents 45 * of the current one (for example {@link #transform}) 46 * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or 47 * array (for example {@link #toList}) 48 * <li>element extraction methods which facilitate the retrieval of certain elements (for example 49 * {@link #last}) 50 * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example 51 * {@link #anyMatch}) 52 * </ul> 53 * 54 * <p>Here is an example that merges the lists returned by two separate database calls, transforms 55 * it by invoking {@code toString()} on each element, and returns the first 10 elements as an 56 * {@code ImmutableList}: <pre> {@code 57 * 58 * FluentIterable 59 * .from(database.getClientList()) 60 * .filter(activeInLastMonth()) 61 * .transform(Functions.toStringFunction()) 62 * .limit(10) 63 * .toList();}</pre> 64 * 65 * <p>Anything which can be done using {@code FluentIterable} could be done in a different fashion 66 * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of 67 * operations significantly more concise. 68 * 69 * @author Marcin Mikosik 70 * @since 12.0 71 */ 72 @GwtCompatible(emulated = true) 73 public abstract class FluentIterable<E> implements Iterable<E> { 74 // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof 75 // checks on the _original_ iterable when FluentIterable.from is used. 76 private final Iterable<E> iterable; 77 78 /** Constructor for use by subclasses. */ 79 protected FluentIterable() { 80 this.iterable = this; 81 } 82 83 FluentIterable(Iterable<E> iterable) { 84 this.iterable = checkNotNull(iterable); 85 } 86 87 /** 88 * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it 89 * is already a {@code FluentIterable}. 90 */ 91 public static <E> FluentIterable<E> from(final Iterable<E> iterable) { 92 return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable 93 : new FluentIterable<E>(iterable) { 94 @Override 95 public Iterator<E> iterator() { 96 return iterable.iterator(); 97 } 98 }; 99 } 100 101 /** 102 * Construct a fluent iterable from another fluent iterable. This is obviously never necessary, 103 * but is intended to help call out cases where one migration from {@code Iterable} to 104 * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}. 105 * 106 * @deprecated instances of {@code FluentIterable} don't need to be converted to 107 * {@code FluentIterable} 108 */ 109 @Deprecated 110 public static <E> FluentIterable<E> from(FluentIterable<E> iterable) { 111 return checkNotNull(iterable); 112 } 113 114 /** 115 * Returns a fluent iterable containing {@code elements} in the specified order. 116 * 117 * @since 18.0 118 */ 119 @Beta 120 public static <E> FluentIterable<E> of(E[] elements) { 121 return from(Lists.newArrayList(elements)); 122 } 123 124 /** 125 * Returns a string representation of this fluent iterable, with the format 126 * {@code [e1, e2, ..., en]}. 127 */ 128 @Override 129 public String toString() { 130 return Iterables.toString(iterable); 131 } 132 133 /** 134 * Returns the number of elements in this fluent iterable. 135 */ 136 public final int size() { 137 return Iterables.size(iterable); 138 } 139 140 /** 141 * Returns {@code true} if this fluent iterable contains any object for which 142 * {@code equals(element)} is true. 143 */ 144 public final boolean contains(@Nullable Object element) { 145 return Iterables.contains(iterable, element); 146 } 147 148 /** 149 * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of 150 * this fluent iterable. 151 * 152 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After 153 * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in 154 * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until 155 * this fluent iterable is empty. 156 * 157 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You 158 * should use an explicit {@code break} or be certain that you will eventually remove all the 159 * elements. 160 */ 161 @CheckReturnValue 162 public final FluentIterable<E> cycle() { 163 return from(Iterables.cycle(iterable)); 164 } 165 166 /** 167 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 168 * followed by those of {@code other}. The iterators are not polled until necessary. 169 * 170 * <p>The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding 171 * {@code Iterator} supports it. 172 * 173 * @since 18.0 174 */ 175 @Beta 176 @CheckReturnValue 177 public final FluentIterable<E> append(Iterable<? extends E> other) { 178 return from(Iterables.concat(iterable, other)); 179 } 180 181 /** 182 * Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable, 183 * followed by {@code elements}. 184 * 185 * @since 18.0 186 */ 187 @Beta 188 @CheckReturnValue 189 public final FluentIterable<E> append(E... elements) { 190 return from(Iterables.concat(iterable, Arrays.asList(elements))); 191 } 192 193 /** 194 * Returns the elements from this fluent iterable that satisfy a predicate. The 195 * resulting fluent iterable's iterator does not support {@code remove()}. 196 */ 197 @CheckReturnValue 198 public final FluentIterable<E> filter(Predicate<? super E> predicate) { 199 return from(Iterables.filter(iterable, predicate)); 200 } 201 202 /** 203 * Returns the elements from this fluent iterable that are instances of class {@code type}. 204 * 205 * @param type the type of elements desired 206 */ 207 @GwtIncompatible("Class.isInstance") 208 @CheckReturnValue 209 public final <T> FluentIterable<T> filter(Class<T> type) { 210 return from(Iterables.filter(iterable, type)); 211 } 212 213 /** 214 * Returns {@code true} if any element in this fluent iterable satisfies the predicate. 215 */ 216 public final boolean anyMatch(Predicate<? super E> predicate) { 217 return Iterables.any(iterable, predicate); 218 } 219 220 /** 221 * Returns {@code true} if every element in this fluent iterable satisfies the predicate. 222 * If this fluent iterable is empty, {@code true} is returned. 223 */ 224 public final boolean allMatch(Predicate<? super E> predicate) { 225 return Iterables.all(iterable, predicate); 226 } 227 228 /** 229 * Returns an {@link Optional} containing the first element in this fluent iterable that 230 * satisfies the given predicate, if such an element exists. 231 * 232 * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null} 233 * is matched in this fluent iterable, a {@link NullPointerException} will be thrown. 234 */ 235 public final Optional<E> firstMatch(Predicate<? super E> predicate) { 236 return Iterables.tryFind(iterable, predicate); 237 } 238 239 /** 240 * Returns a fluent iterable that applies {@code function} to each element of this 241 * fluent iterable. 242 * 243 * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's 244 * iterator does. After a successful {@code remove()} call, this fluent iterable no longer 245 * contains the corresponding element. 246 */ 247 public final <T> FluentIterable<T> transform(Function<? super E, T> function) { 248 return from(Iterables.transform(iterable, function)); 249 } 250 251 /** 252 * Applies {@code function} to each element of this fluent iterable and returns 253 * a fluent iterable with the concatenated combination of results. {@code function} 254 * returns an Iterable of results. 255 * 256 * <p>The returned fluent iterable's iterator supports {@code remove()} if this 257 * function-returned iterables' iterator does. After a successful {@code remove()} call, 258 * the returned fluent iterable no longer contains the corresponding element. 259 * 260 * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0) 261 */ 262 public <T> FluentIterable<T> transformAndConcat( 263 Function<? super E, ? extends Iterable<? extends T>> function) { 264 return from(Iterables.concat(transform(function))); 265 } 266 267 /** 268 * Returns an {@link Optional} containing the first element in this fluent iterable. 269 * If the iterable is empty, {@code Optional.absent()} is returned. 270 * 271 * @throws NullPointerException if the first element is null; if this is a possibility, use 272 * {@code iterator().next()} or {@link Iterables#getFirst} instead. 273 */ 274 public final Optional<E> first() { 275 Iterator<E> iterator = iterable.iterator(); 276 return iterator.hasNext() 277 ? Optional.of(iterator.next()) 278 : Optional.<E>absent(); 279 } 280 281 /** 282 * Returns an {@link Optional} containing the last element in this fluent iterable. 283 * If the iterable is empty, {@code Optional.absent()} is returned. 284 * 285 * @throws NullPointerException if the last element is null; if this is a possibility, use 286 * {@link Iterables#getLast} instead. 287 */ 288 public final Optional<E> last() { 289 // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE 290 291 // TODO(kevinb): Support a concurrently modified collection? 292 if (iterable instanceof List) { 293 List<E> list = (List<E>) iterable; 294 if (list.isEmpty()) { 295 return Optional.absent(); 296 } 297 return Optional.of(list.get(list.size() - 1)); 298 } 299 Iterator<E> iterator = iterable.iterator(); 300 if (!iterator.hasNext()) { 301 return Optional.absent(); 302 } 303 304 /* 305 * TODO(kevinb): consider whether this "optimization" is worthwhile. Users 306 * with SortedSets tend to know they are SortedSets and probably would not 307 * call this method. 308 */ 309 if (iterable instanceof SortedSet) { 310 SortedSet<E> sortedSet = (SortedSet<E>) iterable; 311 return Optional.of(sortedSet.last()); 312 } 313 314 while (true) { 315 E current = iterator.next(); 316 if (!iterator.hasNext()) { 317 return Optional.of(current); 318 } 319 } 320 } 321 322 /** 323 * Returns a view of this fluent iterable that skips its first {@code numberToSkip} 324 * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements, 325 * the returned fluent iterable skips all of its elements. 326 * 327 * <p>Modifications to this fluent iterable before a call to {@code iterator()} are 328 * reflected in the returned fluent iterable. That is, the its iterator skips the first 329 * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()} 330 * is called. 331 * 332 * <p>The returned fluent iterable's iterator supports {@code remove()} if the 333 * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i> 334 * possible to delete the last skipped element by immediately calling {@code remove()} on the 335 * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call 336 * to {@code * remove()} before a call to {@code next()} will throw an 337 * {@link IllegalStateException}. 338 */ 339 @CheckReturnValue 340 public final FluentIterable<E> skip(int numberToSkip) { 341 return from(Iterables.skip(iterable, numberToSkip)); 342 } 343 344 /** 345 * Creates a fluent iterable with the first {@code size} elements of this 346 * fluent iterable. If this fluent iterable does not contain that many elements, 347 * the returned fluent iterable will have the same behavior as this fluent iterable. 348 * The returned fluent iterable's iterator supports {@code remove()} if this 349 * fluent iterable's iterator does. 350 * 351 * @param size the maximum number of elements in the returned fluent iterable 352 * @throws IllegalArgumentException if {@code size} is negative 353 */ 354 @CheckReturnValue 355 public final FluentIterable<E> limit(int size) { 356 return from(Iterables.limit(iterable, size)); 357 } 358 359 /** 360 * Determines whether this fluent iterable is empty. 361 */ 362 public final boolean isEmpty() { 363 return !iterable.iterator().hasNext(); 364 } 365 366 /** 367 * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in 368 * proper sequence. 369 * 370 * @since 14.0 (since 12.0 as {@code toImmutableList()}). 371 */ 372 public final ImmutableList<E> toList() { 373 return ImmutableList.copyOf(iterable); 374 } 375 376 /** 377 * Returns an {@code ImmutableList} containing all of the elements from this {@code 378 * FluentIterable} in the order specified by {@code comparator}. To produce an {@code 379 * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}. 380 * 381 * @param comparator the function by which to sort list elements 382 * @throws NullPointerException if any element is null 383 * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}). 384 */ 385 public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) { 386 return Ordering.from(comparator).immutableSortedCopy(iterable); 387 } 388 389 /** 390 * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with 391 * duplicates removed. 392 * 393 * @since 14.0 (since 12.0 as {@code toImmutableSet()}). 394 */ 395 public final ImmutableSet<E> toSet() { 396 return ImmutableSet.copyOf(iterable); 397 } 398 399 /** 400 * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code 401 * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by 402 * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted 403 * by its natural ordering, use {@code toSortedSet(Ordering.natural())}. 404 * 405 * @param comparator the function by which to sort set elements 406 * @throws NullPointerException if any element is null 407 * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}). 408 */ 409 public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) { 410 return ImmutableSortedSet.copyOf(comparator, iterable); 411 } 412 413 /** 414 * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in 415 * the same order, mapped to values by the given function. If this iterable contains duplicate 416 * elements, the returned map will contain each distinct element once in the order it first 417 * appears. 418 * 419 * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code 420 * valueFunction} produces {@code null} for any key 421 * @since 14.0 422 */ 423 public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) { 424 return Maps.toMap(iterable, valueFunction); 425 } 426 427 /** 428 * Creates an index {@code ImmutableListMultimap} that contains the results of applying a 429 * specified function to each item in this {@code FluentIterable} of values. Each element of this 430 * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same 431 * size as this iterable. The key used to store that value in the multimap will be the result of 432 * calling the function on that value. The resulting multimap is created as an immutable snapshot. 433 * In the returned multimap, keys appear in the order they are first encountered, and the values 434 * corresponding to each key appear in the same order as they are encountered. 435 * 436 * @param keyFunction the function used to produce the key for each value 437 * @throws NullPointerException if any of the following cases is true: 438 * <ul> 439 * <li>{@code keyFunction} is null 440 * <li>An element in this fluent iterable is null 441 * <li>{@code keyFunction} returns {@code null} for any element of this iterable 442 * </ul> 443 * @since 14.0 444 */ 445 public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) { 446 return Multimaps.index(iterable, keyFunction); 447 } 448 449 /** 450 * Returns an immutable map for which the {@link java.util.Map#values} are the elements of this 451 * {@code FluentIterable} in the given order, and each key is the product of invoking a supplied 452 * function on its corresponding value. 453 * 454 * @param keyFunction the function used to produce the key for each value 455 * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one 456 * value in this fluent iterable 457 * @throws NullPointerException if any element of this fluent iterable is null, or if 458 * {@code keyFunction} produces {@code null} for any value 459 * @since 14.0 460 */ 461 public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) { 462 return Maps.uniqueIndex(iterable, keyFunction); 463 } 464 465 /** 466 * Returns an array containing all of the elements from this fluent iterable in iteration order. 467 * 468 * @param type the type of the elements 469 * @return a newly-allocated array into which all the elements of this fluent iterable have 470 * been copied 471 */ 472 @GwtIncompatible("Array.newArray(Class, int)") 473 public final E[] toArray(Class<E> type) { 474 return Iterables.toArray(iterable, type); 475 } 476 477 /** 478 * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to 479 * calling {@code Iterables.addAll(collection, this)}. 480 * 481 * @param collection the collection to copy elements to 482 * @return {@code collection}, for convenience 483 * @since 14.0 484 */ 485 public final <C extends Collection<? super E>> C copyInto(C collection) { 486 checkNotNull(collection); 487 if (iterable instanceof Collection) { 488 collection.addAll(Collections2.cast(iterable)); 489 } else { 490 for (E item : iterable) { 491 collection.add(item); 492 } 493 } 494 return collection; 495 } 496 497 /** 498 * Returns a {@link String} containing all of the elements of this fluent iterable joined with 499 * {@code joiner}. 500 * 501 * @since 18.0 502 */ 503 @Beta 504 public final String join(Joiner joiner) { 505 return joiner.join(this); 506 } 507 508 /** 509 * Returns the element at the specified position in this fluent iterable. 510 * 511 * @param position position of the element to return 512 * @return the element at the specified position in this fluent iterable 513 * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to 514 * the size of this fluent iterable 515 */ 516 public final E get(int position) { 517 return Iterables.get(iterable, position); 518 } 519 520 /** 521 * Function that transforms {@code Iterable<E>} into a fluent iterable. 522 */ 523 private static class FromIterableFunction<E> 524 implements Function<Iterable<E>, FluentIterable<E>> { 525 @Override 526 public FluentIterable<E> apply(Iterable<E> fromObject) { 527 return FluentIterable.from(fromObject); 528 } 529 } 530 }